﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using System.Globalization;

namespace QuanLyHoSoCongChung.App_Code.Common.Utils
{
    class ValidationUtils
    {
        //--------------------------------------------------------------
        #region Public Methods

        /// <summary>
        /// Check email address.
        /// </summary>
        /// <param name="strEmailAddress">Checking email.</param>
        /// <returns>true: OK  false: NG</returns>
        public static bool IsEmailValid(string strEmailAddress)
        {
            bool isOK = true;

            // Chars can input:
            //  Left of @
            //   a-z
            //   A-Z
            //   0-9
            //   .(period)
            //   _(under bar)
            //   -(hyphen)
            //   * ! # $ % & ’ * + / = ? ^ ` { | }
            //   Length: 1->64
            // 
            //  Right of @
            //    a-z
            //    A-Z
            //    0-9
            //    .(period)
            //    -(hyphen)
            //    Length: 4->254
            //  Error cases:
            //   Last char is "." 
            //    
            // => RegEx: ^[0-9a-zA-Z''.'-_'*'!'#'$'%'&'+'/'='?'^'`'{'|'}]{1,64}[@][0-9a-zA-Z.'-]{3,253}[0-9a-zA-Z'-]{1,1}$
            //    ※Comment: Use ' to add one special item to regex
            string strPattern = "\u005e\u005b\u0030\u002d\u0039\u0061\u002d\u007a\u0041\u002d\u005a\u0027\u0027\u002e\u0027\u002d\u005f\u0027\u002a\u0027\u0021\u0027\u0023\u0027\u0024\u0027\u0025\u0027\u0026\u0027\u002b\u0027\u002f\u0027\u003d\u0027\u003f\u0027\u005e\u0027\u0060\u0027\u007b\u0027\u007c\u0027\u007d\u005d\u007b\u0031\u002c\u0036\u0034\u007d\u005b\u0040\u005d\u005b\u0030\u002d\u0039\u0061\u002d\u007a\u0041\u002d\u005a\u002e\u0027\u002d\u005d\u007b\u0033\u002c\u0032\u0035\u0033\u007d\u005b\u0030\u002d\u0039\u0061\u002d\u007a\u0041\u002d\u005a\u0027\u002d\u005d\u007b\u0031\u002c\u0031\u007d\u0024";

            Regex regCheck = new Regex(strPattern);

            isOK = regCheck.IsMatch(strEmailAddress);

            return isOK;
        }

        /// <summary>
        /// Alphabet and numeric
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns>true: OK   false:NG</returns>
        public static bool IsAlphabetOrNumber(string strInputData)
        {
            bool isOK = true;
            Regex regexValidation = new Regex("[^a-zA-Z0-9]");
            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Check Alphabet and numeric and symbols
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns></returns>
        public static bool IsAlphabetOrNumberOrSymbol(string strInputData)
        {
            bool isOK = true;
            string strRegExpression = "\u005b\u005e\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039\u0027\u0060\u0027\u007e\u0027\u0021\u0027\u0040\u0027\u0023\u0027\u0024\u0027\u0025\u0027\u005e\u0027\u0026\u0027\u002a\u0027\u0028\u0027\u0029\u0027\u005f\u0027\u002b\u0027\u003d\u0027\u007b\u0027\u007d\u0027\u007c\u0027\u003a\u0027\u0022\u0027\u003b\u0027\u0027\u0027\u003c\u0027\u003e\u0027\u003f\u0027\u002f\u0027\u002e\u0027\u002c\u005c\u002d\u005b\u005c\u005d\u005c\u005c\u005d";
            // a-zA-Z0-9`~!@#$%^&*()_+=-{}|\][:";'<>?/.,
            // => RegEx: [^a-zA-Z0-9'`'~'!'@'#'$'%'^'&'*'(')'_'+'='{'}'|':'"';'''<'>'?'/'.',\-[\]\\]
            // ※Comment: use ' and \ to add special chars

            Regex regexValidation = new Regex(strRegExpression);
            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Check symbols
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns></returns>
        public static bool IsSymbol(string strInputData)
        {
            bool isOK = true;
            string strRegExpression = "\u005b\u005e\u0027\u0060\u0027\u007e\u0027\u0021\u0027\u0040\u0027\u0023\u0027\u0024\u0027\u0025\u0027\u005e\u0027\u0026\u0027\u002a\u0027\u0028\u0027\u0029\u0027\u005f\u0027\u002b\u0027\u003d\u0027\u007b\u0027\u007d\u0027\u007c\u0027\u003a\u0027\u0022\u0027\u003b\u0027\u0027\u0027\u003c\u0027\u003e\u0027\u003f\u0027\u002f\u0027\u002e\u0027\u002c\u005c\u002d\u005b\u005c\u005d\u005c\u005c\u005d";
            // Characters: `~!@#$%^&*()_+=-{}|\][:";'<>?/.,
            // => RegEx: [^'`'~'!'@'#'$'%'^'&'*'(')'_'+'='{'}'|':'"';'''<'>'?'/'.',\-[\]\\]
            // ※Comment: use ' and \ to add special chars

            Regex regexValidation = new Regex(strRegExpression);
            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Alphabet
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns>true: OK   false:NG</returns>
        public static bool IsAlphabet(string strInputData)
        {
            bool isOK = true;
            Regex regexValidation = new Regex("[^a-zA-Z]");

            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Alphabet upper case
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns>true: OK   false:NG</returns>
        public static bool IsAlphabetUpperCase(string strInputData)
        {
            bool isOK = true;
            Regex regexValidation = new Regex("[^A-Z]");

            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Alphabet lower case
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns>true: OK   false:NG</returns>
        public static bool IsAlphabetLowerCase(string strInputData)
        {
            bool isOK = true;
            Regex regexValidation = new Regex("[^a-z]");

            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Number
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns></returns>
        public static bool IsNumber(string strInputData)
        {
            bool isOK = true;
            Regex regexValidation = new Regex("[^0-9]");

            if (regexValidation.Match(strInputData).Success)
            {
                isOK = false;
            }

            return isOK;
        }

        /// <summary>
        /// Check length of input data is less than maxlength or not
        /// </summary>
        /// <param name="strInputData"></param>
        /// <param name="nMaxBytelen"></param>
        /// <returns></returns>
        public static bool CheckMaxbytes(string strInputData, int nMaxBytelen)
        {
            bool isOK = true;
            if (ProjectUtils.GetByteCount(strInputData) > nMaxBytelen)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Check length of input data is greater than minlength or not
        /// </summary>
        /// <param name="strInputData"></param>
        /// <param name="nMinBytelen"></param>
        /// <returns></returns>
        public static bool CheckMinbytes(string strInputData, int nMinBytelen)
        {
            bool isOK = true;
            if (ProjectUtils.GetByteCount(strInputData) < nMinBytelen)
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Check requirement.
        /// </summary>
        /// <param name="strInputData"></param>
        /// <returns></returns>
        public static bool CheckRequire(string strInputData)
        {
            bool isOK = true;

            if (string.IsNullOrEmpty(strInputData) || string.IsNullOrEmpty(strInputData.Trim()))
            {
                isOK = false;
            }
            return isOK;
        }

        /// <summary>
        /// Check if input datetime as format: YYYYMMDDHHmmss
        /// </summary>
        /// <param name="strInputDate">Checking datetime</param>
        /// <returns></returns>
        public static bool IsDateTimeAsYYYYMMddHHmmss(string strInputDate)
        {
            bool isOK = false;
            if (strInputDate != null)
            {
                DateTime dateTimeConvert = DateTime.Now;

                if (DateTime.TryParseExact(strInputDate, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTimeConvert))
                {
                    isOK = true;
                }
            }

            return isOK;
        }

        /// <summary>
        /// Check if input datetime as format: YYYYMMDD
        /// </summary>
        /// <param name="strInputDate">Checking datetime</param>
        /// <returns></returns>
        public static bool IsDateTimeAsYYYYMMDD(string strInputDate)
        {
            bool isOK = false;
            if (strInputDate != null)
            {
                DateTime dateTimeConvert = DateTime.Now;

                if (DateTime.TryParseExact(strInputDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTimeConvert))
                {
                    isOK = true;
                }
            }

            return isOK;

        }

        /// <summary>
        /// Check if input month as format: YYYYMM
        /// </summary>
        /// <param name="strInputDate">Checking month</param>
        /// <returns></returns>
        public static bool IsMonthAsYYYYMM(string strInputMonth)
        {
            bool isOK = false;
            if (strInputMonth != null)
            {
                DateTime dateTimeConvert = DateTime.Now;

                if (DateTime.TryParseExact(strInputMonth + "01", "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTimeConvert))
                {
                    isOK = true;
                }
            }

            return isOK;

        }

        /// <summary>
        /// IsDateValid
        /// </summary>
        /// <param name="strYear">Year</param>
        /// <param name="strMonth">Month</param>
        /// <param name="strDay">Day</param>
        /// <returns></returns>
        public static bool IsDateValid(string strYear, string strMonth, string strDay)
        {
            bool isOK = false;

            int nTemp = 0;
            if (int.TryParse(strYear, out nTemp)
                && int.TryParse(strMonth, out nTemp)
                && int.TryParse(strDay, out nTemp))
            {
                string strCombineDate = strYear.PadLeft(4, '0') + strMonth.PadLeft(2, '0') + strDay.PadLeft(2, '0');
                DateTime dateTemp = DateTime.MinValue;
                if (DateTime.TryParseExact(strCombineDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTemp))
                {
                    isOK = true;
                }
            }

            return isOK;
        }

        /// <summary>
        /// Check item by specified regular expression
        /// </summary>
        /// <param name="strInputValue">Item to check</param>
        /// <param name="strRegExPattern">Pattern of regular expression</param>
        /// <returns></returns>
        public static bool CheckRegEx(string strInputValue, string strRegExPattern)
        {
            bool isOK = true;
            if (!string.IsNullOrEmpty(strRegExPattern))
            {
                Regex regCheck = new Regex(strRegExPattern);
                if (!regCheck.IsMatch(strInputValue))
                {
                    isOK = false;
                }
            }

            return isOK;
        }

        #endregion Public Methods
        //--------------------------------------------------------------
    }
}
